/*
 * @Author: LVGRAPE
 * @LastEditors: LVGRAPE
 */
#ifndef __DRV_SOFT_I2C_H__
#define __DRV_SOFT_I2C_H__

#include <rtthread.h>
#include <rthw.h>
#include "at32f413.h"
#include "board.h"

#ifdef __cplusplus
extern "C"
{
#endif

    typedef struct soft_i2c
    {
        gpio_type *scl_port;
        gpio_type *sda_port;
        uint8_t scl_pin;
        uint8_t sda_pin;
        uint32_t freq;
        uint8_t delay;
        struct rt_mutex lock;

        int8_t (*start)(struct soft_i2c *self);
        int8_t (*stop)(struct soft_i2c *self);
        int8_t (*send_byte)(struct soft_i2c *self, uint8_t byte);
        int8_t (*recv_byte)(struct soft_i2c *self, uint8_t *byte);
        int8_t (*wait_ack)(struct soft_i2c *self);
        int8_t (*send_ack_or_nack)(struct soft_i2c *self, int8_t ack);
        int8_t (*write)(struct soft_i2c *self, uint8_t slavAddr, uint8_t reg, uint8_t *data, uint16_t len);
        int8_t (*read)(struct soft_i2c *self, uint8_t slavAddr, uint8_t reg, uint8_t *data, uint16_t len);
    } soft_i2c_t;

    int8_t soft_i2c_init(soft_i2c_t *self, gpio_type *scl_port, uint16_t scl_pin, gpio_type *sda_port,  uint16_t sda_pin, uint32_t freq);
    void soft_i2c_start(soft_i2c_t *self);
    void soft_i2c_stop(soft_i2c_t *self);
    int8_t soft_i2c_send_byte(soft_i2c_t *self, uint8_t byte);
    uint8_t soft_i2c_recv_byte(soft_i2c_t *self, int8_t ack);
    rt_bool_t soft_i2c_wait_ack(soft_i2c_t *self);
    int8_t soft_i2c_send_ack_or_nack(soft_i2c_t *self, int8_t ack);
    int32_t soft_i2c_write(soft_i2c_t *self, uint8_t slavAddr, uint8_t reg, uint8_t *data, uint16_t len);
    int32_t soft_i2c_read(soft_i2c_t *self, uint8_t slavAddr, uint8_t reg, uint8_t *data, uint16_t len);
    void soft_i2c1_init(void);
    uint8_t soft_i2c1_scan(void);
    int32_t soft_i2c1_read(uint8_t slavAddr, uint8_t reg, uint8_t *data, uint16_t len);
    int32_t soft_i2c1_write(uint8_t slavAddr, uint8_t reg, uint8_t *data, uint16_t len);

#ifdef __cplusplus
}
#endif

#endif /* __DRV_SOFT_I2C_H__ */
